package net.tavion.angelboot.swagger2;

import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMethod;
import springfox.documentation.builders.*;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.service.ResponseMessage;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebFlux;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableSwagger2WebFlux
@ComponentScan(basePackages = "net.tavion.angelboot")
@Profile({"dev","sit","uat"})
public class WebfluxSwaggerConfig implements EnvironmentAware {

    private Environment environment;
    @Override
    public void setEnvironment(Environment environment) {
        this.environment=environment;
    }

    @Bean
    public Docket swagger2UIDocket(){
        String appName=this.environment.getProperty("spring.application.name");

        ApiSelectorBuilder apiSelectorBuilder=new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(swaggerApiInfo())
                .globalOperationParameters(createGlobalOperationParameters())
                .globalResponseMessage(RequestMethod.POST, responseMessages())
                .globalResponseMessage(RequestMethod.PUT, responseMessages())
                .globalResponseMessage(RequestMethod.DELETE, responseMessages())
                .globalResponseMessage(RequestMethod.GET, responseMessages())
                .globalResponseMessage(RequestMethod.PATCH, responseMessages())
                .globalResponseMessage(RequestMethod.OPTIONS, responseMessages())
                .globalResponseMessage(RequestMethod.TRACE, responseMessages())
                .select()
                //.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any());

        if(appName.equalsIgnoreCase("FGW")){

        }

        return apiSelectorBuilder.build();
    }

    /**
     * 自定义API文档基本信息实体
     * @return
     */
    private ApiInfo swaggerApiInfo(){
        //构建联系实体，在UI界面会显示
        Contact contact = new Contact("方丈", "https://gitee.com/tone-fangzhang", "13787205736@163.com");
        return new ApiInfoBuilder()
                .contact(contact)
                //文档标题
                .title(getTitle())
                //文档描述
                .description("angelboot Swagger2构建webflux restful API文档")
                //文档版本
                .version("1.0.0")
                .build() ;
    }

    private String getTitle() {
        return "angelboot APIs for " + this.environment.getProperty("spring.application.name");
    }


    private List createGlobalOperationParameters(){
        List<Parameter> parameters = new ArrayList<Parameter>();

        parameters.add(new ParameterBuilder().name("x-usrid").description("用户ID")
                .defaultValue(null)
                .parameterType("header").required(false)
                .modelRef(new ModelRef("string")).build());
        parameters.add(new ParameterBuilder().name("x-channel").description("访问渠道编码")
                .defaultValue(null)
                .parameterType("header")
                .modelRef(new ModelRef("string")).build());
        parameters.add(new ParameterBuilder().name("x-language").description("语言")
                .defaultValue("en_US")
                .parameterType("header")
                .modelRef(new ModelRef("string")).build());
        parameters.add(new ParameterBuilder().name("Authorization").description("认证token")
                .defaultValue("Bearer ")
                .parameterType("header").required(false)
                .modelRef(new ModelRef("string")).build());
        return parameters;
    }

    private List<ResponseMessage> responseMessages() {
        List<ResponseMessage> responses = new ArrayList<>();
        responses.add(new ResponseMessageBuilder().code(200).message("success").build());
        responses.add(new ResponseMessageBuilder().code(500).message("server inner error").build());
        responses.add(new ResponseMessageBuilder().code(403).message("permission refuse").build());
        responses.add(new ResponseMessageBuilder().code(404).message("resource not found").build());
        responses.add(new ResponseMessageBuilder().code(691).message("user login fail").build());
        responses.add(new ResponseMessageBuilder().code(692).message("token illegality").build());
        responses.add(new ResponseMessageBuilder().code(693).message("token expired").build());
        responses.add(new ResponseMessageBuilder().code(694).message("force modify password").build());
        responses.add(new ResponseMessageBuilder().code(695).message("user freeze").build());
        responses.add(new ResponseMessageBuilder().code(696).message("user locked").build());
        return responses;
    }
}
